﻿using System.Web;
using System.Globalization;
using System;
using OpenPhotoAlbum.BusinessLogics;

namespace OpenPhotoAlbum
{
	public static class Links
	{
		private static string ToAbsolute(string link) { return VirtualPathUtility.ToAbsolute(link); }

		public static readonly string Default = ToAbsolute("~/Default.aspx");
		public static readonly string PhotoPipe = ToAbsolute("~/PhotoPipe.ashx");
		public static readonly string MyHome = ToAbsolute("~/My/Home.aspx");
		public static readonly string MyAlbum = ToAbsolute("~/My/Album.aspx");
		public static readonly string MyPhoto = ToAbsolute("~/My/Photo.aspx");
		public static readonly string MySettings = ToAbsolute("~/My/Settings.aspx");
		public static readonly string Join = ToAbsolute("~/Join.aspx");
		public static readonly string SharedHome = ToAbsolute("~/Shared/Home.aspx");
		public static readonly string SharedHomeJump = ToAbsolute("~/r.ashx");
		public static readonly string SharedAlbum = ToAbsolute("~/Shared/Album.aspx");
		public static readonly string SharedPhoto = ToAbsolute("~/Shared/Photo.aspx");
		public static readonly string PostPadCanvas = ToAbsolute("~/Controls/PostPadCanvas.jpg");
		public static readonly string PasswordRecovery = ToAbsolute("~/PasswordRecovery.aspx");
		public static readonly string DefaultUserIcon = ToAbsolute("~/Shared/Icon.png");
		public static readonly string Login = ToAbsolute("~/Login.aspx");
		public static readonly string UserAgreement = ToAbsolute("~/UserAgreement.pdf");

		public static string ToFullPath(string absolutePath)
		{
			Uri url = HttpContext.Current.Request.Url;
			return Controls.StringUtility.FormatWithInvariantCulture(
				"{0}://{1}{2}",
				url.Scheme,
				url.Port == 80 ? url.Host : url.Host + ":" + url.Port,
				absolutePath);
		}
	}

	public static class UrlContext
	{
		public static int HomePageNumber { get { return int.Parse(QueryString(UrlFormats.PARAMETER_NAME_HOME_PAGE_NUMBER)); } }
		public static Guid AlbumId { get { return TryParseGuid(QueryString(UrlFormats.PARAMETER_NAME_ALBUM_ID)); } }
		public static string AlbumTitle { get { return QueryString(UrlFormats.PARAMETER_NAME_ALBUM_TITLE); } }
		public static int AlbumPageNumber { get { return int.Parse(QueryString(UrlFormats.PARAMETER_NAME_ALBUM_PAGE_NUMBER)); } }
		public static Guid PhotoId { get { return TryParseGuid(QueryString(UrlFormats.PARAMETER_NAME_PHOTO_ID)); } }
		public static string PhotoType { get { return QueryString(UrlFormats.PARAMETER_NAME_PHOTO_TYPE); } }
		public static string PhotoCaption { get { return QueryString(UrlFormats.PARAMETER_NAME_PHOTO_CAPTION); } }
		public static Guid UserId { get { return TryParseGuid(QueryString(UrlFormats.PARAMETER_NAME_USER_ID)); } }
		public static string UserName { get { return QueryString(UrlFormats.PARAMETER_NAME_USER_NAME); } }
		public static Guid Key { get { return TryParseGuid(QueryString(UrlFormats.PARAMETER_NAME_KEY)); } }
		public static string Data { get { return QueryString(UrlFormats.PARAMETER_NAME_DATA); } }
		public static int VisibleIndex { get { return int.Parse(QueryString(UrlFormats.PARAMETER_NAME_VISIBLE_INDEX)); } }
		public static string VisualEffect { get { return QueryString(UrlFormats.PARAMETER_NAME_VISUAL_EFFECT); } }

		public static Guid TryParseGuid(string value)
		{
			if (string.IsNullOrEmpty(value)) { return Guid.Empty; }
			else { return new Guid(value); }
		}

		public static string QueryString(string key)
		{
			string value = HttpContext.Current.Request.QueryString[key];
			if (string.IsNullOrEmpty(value)) { return null; }
			else { return value; }
		}

		public static string BuildMyHomeUrl(int homePageNumber)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_MY_HOME,
				Links.MyHome,
				homePageNumber);
		}
		public static string BuildMyAlbumUrl(int homePageNumber, Guid albumId, string albumTitle, int albumPageNumber)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_MY_ALBUM,
				Links.MyAlbum,
				homePageNumber,
				albumId,
				HttpUtility.UrlEncode(albumTitle),
				albumPageNumber);
		}
		public static string BuildMyPhotoUrl(int homePageNumber, int albumPageNumber, Guid photoId, string photoCaption)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_MY_PHOTO,
				Links.MyPhoto,
				homePageNumber,
				AlbumId,
				HttpUtility.UrlEncode(AlbumTitle),
				albumPageNumber,
				photoId,
				HttpUtility.UrlEncode(photoCaption));
		}
		public static string BuildMyPhotoUrl(int homePageNumber, int albumPageNumber, Guid albumId, string albumTitle, Guid photoId, string photoCaption)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_MY_PHOTO,
				Links.MyPhoto,
				homePageNumber,
				albumId,
				HttpUtility.UrlEncode(albumTitle),
				albumPageNumber,
				photoId,
				HttpUtility.UrlEncode(photoCaption));
		}
		public static string BuildPhotoPipeUrl(Guid photoId, string photoType)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_PHOTOPIPE,
				Links.PhotoPipe,
				photoId,
				photoType);
		}
		public static string BuildPhotoPipeVisualEffectUrl(Guid photoId, string photoType, string effect)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_PHOTOPIPE_VE,
				Links.PhotoPipe,
				photoId,
				photoType,
				effect);
		}
		public static string BuildPhotoPipeCaptchaUrl(string data)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_PHOTOPIPE_CAPTCH,
				Links.PhotoPipe,
				PhotoTypes.Captcha,
				data);
		}
		public static string BuildPhotoPipeUserIconUrl(Guid? userId)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_PHOTOPIPE_USER_ICON,
				Links.PhotoPipe,
				PhotoTypes.UserIcon,
				userId);
		}
		public static string BuildSharedHomeUrl(string userName)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_SHARED_HOME_SHORT,
				Links.SharedHomeJump,
				HttpUtility.UrlEncode(userName));
		}
		public static string BuildSharedHomeUrl(Guid userId)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_SHARED_HOME,
				Links.SharedHome,
				userId);
		}
		public static string BuildSharedAlbumUrl(Guid albumId)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_SHARED_ALBUM,
				Links.SharedAlbum,
				albumId);
		}
		public static string BuildSharedPhotoUrl(Guid photoId)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_SHARED_PHOTO,
				Links.SharedPhoto,
				photoId);
		}
		public static string BuildPasswordRecoveryUrl(Guid key)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_PASSWORD_RECOVERY,
				Links.PasswordRecovery,
				key);
		}
		public static string BuildMySettingsUrl(int visibleIndex)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_MY_SETTINGS,
				Links.MySettings,
				visibleIndex);
		}
		public static string BuildLoginUrl(string userName)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_LOGIN,
				Links.Login,
				HttpUtility.UrlEncode(userName));
		}
		public static string BuildLoginUrl(int index)
		{
			return UrlFormats.Format(
				UrlFormats.URL_FORMAT_LOGIN_INDEX,
				Links.Login,
				index);
		}
	}

	public static class UrlFormats
	{
		public const string PARAMETER_NAME_HOME_PAGE_NUMBER = "hp";
		public const string PARAMETER_NAME_ALBUM_ID = "a";
		public const string PARAMETER_NAME_ALBUM_TITLE = "at";
		public const string PARAMETER_NAME_ALBUM_PAGE_NUMBER = "ap";
		public const string PARAMETER_NAME_PHOTO_ID = "p";
		public const string PARAMETER_NAME_PHOTO_TYPE = "t";
		public const string PARAMETER_NAME_PHOTO_CAPTION = "c";
		public const string PARAMETER_NAME_USER_ID = "i";
		public const string PARAMETER_NAME_USER_NAME = "u";
		public const string PARAMETER_NAME_KEY = "k";
		public const string PARAMETER_NAME_DATA = "d";
		public const string PARAMETER_NAME_VISIBLE_INDEX = "vi";
		public const string PARAMETER_NAME_VISUAL_EFFECT = "v";

		/// <summary>
		/// Url format of my home.
		/// {0}:link;
		/// {1}:home page number
		/// </summary>
		public const string URL_FORMAT_MY_HOME = "{0}?hp={1}";

		/// <summary>
		/// Url format of my album.
		/// {0}:link;
		/// {1}:home page number;
		/// {2}:album id;
		/// {3}:album title;
		/// {4}:album page number.
		/// </summary>
		public const string URL_FORMAT_MY_ALBUM = "{0}?hp={1}&a={2}&at={3}&ap={4}";

		/// <summary>
		/// Url format of my photo.
		/// {0}:link;
		/// {1}:home page number;
		/// {2}:album id;
		/// {3}:album title;
		/// {4}:album page number;
		/// {5}:photo id;
		/// {6}:photo caption.
		/// </summary>
		public const string URL_FORMAT_MY_PHOTO = "{0}?hp={1}&a={2}&at={3}&ap={4}&p={5}&c={6}";

		/// <summary>
		/// Url format of photo pipe.
		/// {0}:link;
		/// {1}:photo id;
		/// {2}:photo type.
		/// </summary>
		public const string URL_FORMAT_PHOTOPIPE = "{0}?p={1}&t={2}";

		public const string URL_FORMAT_PHOTOPIPE_VE = "{0}?p={1}&t={2}&v={3}";

		/// <summary>
		/// Url format of photo pipe. (for captch only)
		/// {0}:link
		/// {1}:photo type
		/// {2}:data
		/// </summary>
		public const string URL_FORMAT_PHOTOPIPE_CAPTCH = "{0}?t={1}&d={2}";

		/// <summary>
		/// Url format of user icon.
		/// {0}:link
		/// {1}:photo type
		/// {2}:user id
		/// </summary>
		public const string URL_FORMAT_PHOTOPIPE_USER_ICON = "{0}?t={1}&i={2}";

		/// <summary>
		/// Url format of shared home.
		/// {0}:link;
		/// {1}:user id.
		/// </summary>
		public const string URL_FORMAT_SHARED_HOME = "{0}?i={1}";

		public const string URL_FORMAT_SHARED_HOME_SHORT = "{0}?u={1}";

		/// <summary>
		/// Url format of shared album.
		/// {0}:link;
		/// {1}:album id;
		/// </summary>
		public const string URL_FORMAT_SHARED_ALBUM = "{0}?a={1}";

		/// <summary>
		/// Url format of shared photo.
		/// {0}:link;
		/// {1}:user id;
		/// {3}:album id;
		/// {4}:album title;
		/// {5}:album page number;
		/// {6}:photo id;
		/// {7}:photo caption.
		/// </summary>
		public const string URL_FORMAT_SHARED_PHOTO = "{0}?p={1}";

		/// <summary>
		/// Url format of password recovery.
		/// {0}: link
		/// {1}: key
		/// </summary>
		public const string URL_FORMAT_PASSWORD_RECOVERY = "{0}?k={1}";

		public const string URL_FORMAT_MY_SETTINGS = "{0}?vi={1}";

		public const string URL_FORMAT_LOGIN = "{0}?u={1}";

		public const string URL_FORMAT_LOGIN_INDEX = "{0}?vi={1}";


		public static string Format(string format, params object[] args)
		{
			return string.Format(CultureInfo.InvariantCulture, format, args);
		}
	}

	public class InvalidUrlFormatException : Exception { }
}